/**
 * Created by Jacky.Gao on 2017-01-31.
 */
import { undoManager } from "../Utils.js";
import { doInsertRow } from "./operation/InsertRowOperation.js";
import { doInsertCol } from "./operation/InsertColOperation.js";
import { doDeleteRow } from "./operation/DeleteRowOperation.js";
import { doDeleteCol } from "./operation/DeleteColOperation.js";
import { renderRowHeader } from "./HeaderUtils.js";
import { MessageBox, Message } from "element-ui";
// import RowColWidthHeightDialog from "../dialog/RowColWidthHeightDialog.js";
import Handsontable from "handsontable";

export default function buildMenuConfigure () {
  return {
    callback: function (key, options) {
      const _this = this;
      if (key === "insert_row_above") {
        doInsertRow.call(this, true);
      } else if (key === "insert_row_below") {
        doInsertRow.call(this);
      } else if (key === "insert_col_left") {
        doInsertCol.call(this, true);
      } else if (key === "insert_col_right") {
        doInsertCol.call(this);
      } else if (key === "del_row") {
        doDeleteRow.call(this);
      } else if (key === "del_col") {
        doDeleteCol.call(this);
      } else if (key === "clean_content") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const startCol = selected[1];
        const endCol = selected[3];
        let removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, "content");
        undoManager.add({
          redo: function () {
            removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, "content");
          },
          undo: function () {
            undoCleanCells(_this.context, startRow, endRow, startCol, endCol, removeCellsMap, "content");
          }
        });
      } else if (key === "clean_style") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const startCol = selected[1];
        const endCol = selected[3];
        let removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, "style");
        undoManager.add({
          redo: function () {
            removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, "style");
          },
          undo: function () {
            undoCleanCells(_this.context, startRow, endRow, startCol, endCol, removeCellsMap, "style");
          }
        });
      } else if (key === "clean") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const startCol = selected[1];
        const endCol = selected[3];
        let removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, "all");
        undoManager.add({
          redo: function () {
            removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, "all");
          },
          undo: function () {
            undoCleanCells(_this.context, startRow, endRow, startCol, endCol, removeCellsMap, "all");
          }
        });
      } else if (key === "repeat_row_header") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const context = this.context;
        for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
          context.addRowHeader(rowNumber, "headerrepeat");
        }
        renderRowHeader(this, context);
        context.isModify = true;
      } else if (key === "title_row") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const context = this.context;
        for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
          context.addRowHeader(rowNumber, "title");
        }
        renderRowHeader(this, context);
        context.isModify = true;
      } else if (key === "repeat_row_footer") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const context = this.context;
        for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
          context.addRowHeader(rowNumber, "footerrepeat");
        }
        renderRowHeader(this, context);
        context.isModify = true;
      } else if (key === "summary_row") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const context = this.context;
        for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
          context.addRowHeader(rowNumber, "summary");
        }
        renderRowHeader(this, context);
        context.isModify = true;
      } else if (key === "repeat_cancel") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const context = this.context;
        for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
          context.adjustDelRowHeaders(rowNumber);
        }
        renderRowHeader(this, context);
        context.isModify = true;
      } else if (key === "row_height") {
        const context = this.context;
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const rowHeight = this.getRowHeight(startRow);
        MessageBox.prompt("请设置行高", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          inputValue: rowHeight
        })
          .then(({ value }) => {
            const rowHeights = this.getSettings().rowHeights;
            rowHeights.splice(startRow, 1, Number(value));
            this.updateSettings({
              rowHeights: rowHeights,
              manualRowResize: rowHeights
            });

            Message.success("行高设置成功！");
          })
          .catch(() => {
            Message.info("取消输入");
          });

        context.isModify = true;
      } else if (key === "col_width") {
        const context = this.context;
        const selected = this.getSelected()[0];
        const startCol = selected[1];
        const colWidth = this.getColWidth(startCol);

        MessageBox.prompt("请设置列宽", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          inputValue: colWidth
        })
          .then(({ value }) => {
            const colWidths = this.getSettings().colWidths;
            colWidths.splice(startCol, 1, Number(value));
            this.updateSettings({
              colWidths: colWidths,
              manualColumnResize: colWidths
            });

            Message.success("列宽设置成功！");
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: "取消输入"
            });
          });
        context.isModify = true;
      } else if (key === "copy_style") {
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        // const endRow = selected[2];
        const startCol = selected[1];
        // const endCol = selected[3];
        const cell = _this.context.getCell(startRow, startCol);
        if (!cell) {
          alert("请先选中目标单元格！");
          return;
        }
        window.__copy_cell_style__ = cell.cellStyle;
      } else if (key === "paste_style") {
        if (!window.__copy_cell_style__) {
          alert("请先复制目标单元格样式");
          return;
        }
        const selected = this.getSelected()[0];
        const startRow = selected[0];
        const endRow = selected[2];
        const startCol = selected[1];
        const endCol = selected[3];
        let oldCellsStyleMap = pasteStyle(_this.context, startRow, endRow, startCol, endCol);
        undoManager.add({
          redo: function () {
            oldCellsStyleMap = pasteStyle(_this.context, startRow, endRow, startCol, endCol);
          },
          undo: function () {
            undoPasteStyle(_this.context, startRow, endRow, startCol, endCol, oldCellsStyleMap);
          }
        });
      }
    },
    items: {
      insert_row_above: {
        name: `<i class="ureport ureport-insertrow" style="color: #3344d3;font-size: 13px"></i> ${window.i18n.table.contextMenu.insertRowUp}`
      },
      insert_row_below: {
        name: `<i class="ureport ureport-insertrow" style="color: #3344d3;font-size: 13px"></i> ${window.i18n.table.contextMenu.insertRowDown}`
      },
      insert_col_left: {
        name: `<i class="ureport ureport-insert-column" style="color: #008ed3;font-size: 13px"></i> ${window.i18n.table.contextMenu.insertColBefore}`
      },
      insert_col_right: {
        name: `<i class="ureport ureport-insert-column" style="color: #008ed3;font-size: 13px"></i> ${window.i18n.table.contextMenu.insertColAfter}`
      },
      del_row: {
        name: `<i class="ureport ureport-deleterow" style="color: #d30a16;font-size: 13px"></i>  ${window.i18n.table.contextMenu.delRow}`,
        disabled: checkRowDeleteOperationDisabled
      },
      del_col: {
        name: `<i class="ureport ureport-deletecolumn" style="color: #d30a16;font-size: 13px"></i>  ${window.i18n.table.contextMenu.delCol}`,
        disabled: checkColDeleteOperationDisabled
      },
      row_height: {
        name: `<i class="ureport ureport-height" style="color: #d30a16;font-size: 13px;font-weight:bold"></i>  ${window.i18n.table.contextMenu.rowHeight}`,
        disabled: checkRowDeleteOperationDisabled
      },
      col_width: {
        name: `<i class="ureport ureport-width" style="color: #d30a16;font-size: 13px;font-weight:bold"></i>  ${window.i18n.table.contextMenu.colWidth}`,
        disabled: checkColDeleteOperationDisabled
      },
      title_row: {
        name: `<i class="ureport ureport-title" style="color: #9C27B0;font-size: 13px"></i>  ${window.i18n.table.contextMenu.title}`,
        disabled: checkRowDeleteOperationDisabled
      },
      repeat_row_header: {
        name: `<i class="ureport ureport-header-repeat" style="color: #9C27B0;font-size: 13px"></i>  ${window.i18n.table.contextMenu.repeatHeader}`,
        disabled: checkRowDeleteOperationDisabled
      },
      repeat_row_footer: {
        name: `<i class="ureport ureport-footer-repeat" style="color: #9C27B0;font-size: 13px"></i>  ${window.i18n.table.contextMenu.repeatFooter}`,
        disabled: checkRowDeleteOperationDisabled
      },
      summary_row: {
        name: `<i class="ureport ureport-summary" style="color: #9C27B0;font-size: 13px"></i>  ${window.i18n.table.contextMenu.summary}`,
        disabled: checkRowDeleteOperationDisabled
      },
      repeat_cancel: {
        name: `<i class="glyphicon glyphicon-remove-circle" style="color: #d30e00;font-size: 13px"></i>  ${window.i18n.table.contextMenu.cancel}`,
        disabled: checkRowDeleteOperationDisabled
      },
      copy_style: {
        name: `<i class="ureport ureport-copy" style="color: #d30e00;font-size: 13px"></i>  ${window.i18n.table.contextMenu.copy}`,
        disabled: checkCopyOperationDisabled
      },
      paste_style: {
        name: `<i class="ureport ureport-paste" style="color: #d30e00;font-size: 13px"></i>  ${window.i18n.table.contextMenu.paste}`,
        disabled: checkPasteOperationDisabled
      },
      clean_content: {
        name: `<i class="ureport ureport-clean-content" style="color: #007471;font-size: 13px"></i>  ${window.i18n.table.contextMenu.clearContent}`,
        disabled: checkCleanOperationDisabled
      },
      clean_style: {
        name: `<i class="ureport ureport-clean-style" style="color: #00746f;font-size: 13px"></i>  ${window.i18n.table.contextMenu.clearStyle}`,
        disabled: checkCleanOperationDisabled
      },
      clean: {
        name: `<i class="ureport ureport-clean" style="color: #d30e00;font-size: 13px"></i>  ${window.i18n.table.contextMenu.clearAll}`,
        disabled: checkCleanOperationDisabled
      }
    }
  };

  function undoCleanCells (context, startRow, endRow, startCol, endCol, removeCellsMap, type) {
    // const cellsMap = context.cellsMap;
    const hot = context.hot;
    for (let i = startRow; i <= endRow; i++) {
      for (let j = startCol; j <= endCol; j++) {
        const cell = context.getCell(i, j);
        if (!cell) {
          continue;
        }
        const key = cell.rowNumber + "," + cell.columnNumber;
        if (type === "content") {
          const orgValue = removeCellsMap.get(key);
          if (!orgValue) {
            alert(`${window.i18n.table.contextMenu.cancelConetntFail}`);
            return;
          }
          cell.value = orgValue;
          const value = cell.value;
          const valueType = value.type;
          let text = value.value;
          if (valueType === "dataset") {
            text = value.datasetName + "." + value.aggregate + "(" + value.property + ")";
          }
          hot.setDataAtCell(i, j, text);
        } else if (type === "style") {
          const orgStyle = removeCellsMap.get(key);
          if (!orgStyle) {
            alert(`${window.i18n.table.contextMenu.cancelStyleFail}`);
            return;
          }
          cell.cellStyle = orgStyle;
        } else if (type === "all") {
          context.removeCell(cell);
          const orgCell = removeCellsMap.get(key);
          if (!orgCell) {
            alert(`${window.i18n.table.contextMenu.cancelClearFail}`);
            return;
          }
          context.addCell(orgCell);
          const value = orgCell.value;
          const valueType = value.type;
          let text = value.value;
          if (valueType === "dataset") {
            text = value.datasetName + "." + value.aggregate + "(" + value.property + ")";
          }
          hot.setDataAtCell(i, j, text);
        }
      }
    }
    Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
    hot.render();
  }

  function undoPasteStyle (context, startRow, endRow, startCol, endCol, oldStyleMap) {
    // const style = window.__copy_cell_style__;
    const cellsMap = new Map();
    const hot = context.hot;
    for (let i = startRow; i <= endRow; i++) {
      for (let j = startCol; j <= endCol; j++) {
        const cell = context.getCell(i, j);
        if (!cell) {
          continue;
        }
        const key = cell.rowNumber + "," + cell.columnNumber;
        const oldStyle = oldStyleMap.get(key);
        if (oldStyle) {
          cell.cellStyle = oldStyle;
        }
      }
    }
    Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
    hot.render();
    return cellsMap;
  }

  function pasteStyle (context, startRow, endRow, startCol, endCol) {
    const style = window.__copy_cell_style__;
    const cellsMap = new Map();
    const hot = context.hot;
    for (let i = startRow; i <= endRow; i++) {
      for (let j = startCol; j <= endCol; j++) {
        const cell = context.getCell(i, j);
        if (!cell) {
          continue;
        }
        const key = cell.rowNumber + "," + cell.columnNumber;
        if (!cell.cellStyle) {
          cell.cellStyle = {};
        }
        const oldStyle = JSON.parse(JSON.stringify(cell.cellStyle));
        cellsMap.set(key, oldStyle);
        cell.cellStyle.fontSize = style.fontSize;
        cell.cellStyle.forecolor = style.forecolor;
        cell.cellStyle.fontFamily = style.fontFamily;
        cell.cellStyle.valign = style.valign;
        cell.cellStyle.align = style.align;
        cell.cellStyle.bgcolor = style.bgcolor;
        cell.cellStyle.bold = style.bold;
        cell.cellStyle.italic = style.italic;
        cell.cellStyle.underline = style.underline;
      }
    }
    Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
    hot.render();
    return cellsMap;
  }

  function cleanCells (context, startRow, endRow, startCol, endCol, type) {
    const removeCellsMap = new Map();
    const hot = context.hot;
    for (let i = startRow; i <= endRow; i++) {
      for (let j = startCol; j <= endCol; j++) {
        const cell = context.getCell(i, j);
        if (!cell) {
          continue;
        }
        cell.cellStyle.format = null;
        const key = cell.rowNumber + "," + cell.columnNumber;
        if (type === "content") {
          removeCellsMap.set(key, cell.value);
          cell.value = {
            type: "simple",
            value: ""
          };
          cell.expand = "None";
          cell.conditionPropertyItems = null;
          hot.setDataAtCell(i, j, "");
        } else if (type === "style") {
          removeCellsMap.set(key, cell.cellStyle);
          cell.cellStyle = { fontSize: 9, forecolor: "0,0,0", fontFamily: "宋体", align: "center", valign: "middle" };
        } else if (type === "all") {
          context.removeCell(cell);
          removeCellsMap.set(key, cell);
          const newCell = {
            rowNumber: cell.rowNumber,
            columnNumber: cell.columnNumber,
            expand: "None",
            value: {
              type: "simple",
              value: ""
            },
            cellStyle: { fontSize: 9, forecolor: "0,0,0", fontFamily: "宋体", align: "center", valign: "middle" }
          };
          context.addCell(newCell);
          hot.setDataAtCell(i, j, "");
        }
      }
    }
    Handsontable.hooks.run(hot, "afterSelectionEnd", startRow, startCol, endRow, endCol);
    hot.render();
    return removeCellsMap;
  }

  function checkCopyOperationDisabled () {
    const selected = this.getSelected()[0];
    if (!selected) {
      return true;
    }
    return false;
  }
  function checkPasteOperationDisabled () {
    const selected = this.getSelected()[0];
    if (!selected) {
      return true;
    }
    if (window.__copy_cell_style__) {
      return false;
    }
    return true;
  }
  function checkRowDeleteOperationDisabled () {
    const selected = this.getSelected()[0];
    if (!selected) {
      return true;
    }
    const startRow = selected[0];
    const endRow = selected[2];
    const dif = Math.abs(startRow - endRow) + 1;
    const countRows = this.countRows();
    if (dif >= countRows) {
      return true;
    } else {
      return false;
    }
  }

  function checkColDeleteOperationDisabled () {
    const selected = this.getSelected()[0];
    if (!selected) {
      return true;
    }
    const startCol = selected[1];
    const endCol = selected[3];
    const dif = Math.abs(startCol - endCol) + 1;
    const countCols = this.countCols();
    if (dif >= countCols) {
      return true;
    } else {
      return false;
    }
  }
  function checkCleanOperationDisabled () {
    const selected = this.getSelected()[0];
    if (!selected || selected.length === 0) {
      return true;
    }
    return false;
  }
}
